package smartbooksdb.service;

import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

import smartbooksdb.exception.UserException;
import smartbooksdb.hibernatebean.User;
import smartbooksdb.util.CommonConstantsDB;
import smartbooksdb.util.ErrorLogger;
import smartbooksdb.valuebean.Credentials;

@SuppressWarnings("unchecked")
class UserDAO implements CommonConstantsDB {
	private static UserDAO userDAO;

	/**
	 * Singleton pattern is implemented for UserDAO. The 'new' keyword should
	 * not be used to instantiate an object of this class. This method should be
	 * used to get an instance of this dao class.
	 * 
	 * @return userDAO
	 */
	protected static UserDAO getInstance() {
		if (null == userDAO) {
			userDAO = new UserDAO();
		}
		return userDAO;
	}

	protected long getNumberOfAdmin() {
		Session session = HibernateUtil.getSessionFactory().openSession();
		try {
			String sqlQuery = "SELECT COUNT(u) FROM User u WHERE u.role = '"
					+ ADMIN + "' AND u.status = '" + ACTIVE + "'";
			Query query = session.createQuery(sqlQuery);

			List<Long> user = query.list();
			if (null != user) {
				return user.get(0);
			}
		} finally {
			session.close();
		}
		return 0;
	}

	protected boolean isUsernameAvailable(String username,
			boolean isCaseSensitive) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		try {
			String sqlQuery = "";
			if (isCaseSensitive) {
				sqlQuery = "SELECT COUNT(u) FROM User u WHERE u.username = '"
						+ username + "'";
			} else {
				sqlQuery = "SELECT COUNT(u) FROM User u WHERE LOWER(u.username) = '"
						+ username.toLowerCase() + "'";
			}
			Query query = session.createQuery(sqlQuery);

			List<Long> user = query.list();
			if (null != user && user.get(0) > 0) {
				return false;
			}
		} finally {
			session.close();
		}
		return true;
	}

	protected void createUser(User user) throws UserException {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction transaction = null;

		try {
			transaction = session.beginTransaction();
			session.save(user);
			transaction.commit();
		} catch (HibernateException ex) {
			ErrorLogger.log(ex, SEND_MAIL);
			transaction.rollback();
			if (null != ex.getThrowable(0).getCause()) {
				throw new UserException(ex.getThrowable(0).getCause()
						.getMessage());
			} else if (null != ex.getCause()) {
				throw new UserException(ex.getCause().getMessage());
			} else {
				throw new UserException(ex.getMessage());
			}
		} finally {
			session.close();
		}
	}

	protected User getUser(Credentials credentials) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		try {
			String sqlQuery = "SELECT u FROM User u WHERE u.username = '"
					+ credentials.getUsername() + "' AND u.password = '"
					+ credentials.getPassword() + "' AND u.status = '" + ACTIVE
					+ "'";
			Query query = session.createQuery(sqlQuery);

			List<User> user = query.list();
			if (null != user && user.size() == 1) {
				return user.get(0);
			}
		} finally {
			session.close();
		}
		return null;
	}

	protected List<User> getAllUsers() {
		Session session = HibernateUtil.getSessionFactory().openSession();
		try {
			String sqlQuery = "SELECT u FROM User u WHERE u.status = '"
					+ ACTIVE + "'";
			Query query = session.createQuery(sqlQuery);

			List<User> users = query.list();
			if (null != users) {
				return users;
			}
		} finally {
			session.close();
		}
		return null;
	}
}